package handler

import (
	"encoding/json"
	"focus-single/internal/packed/message"
	"github.com/gogf/gf/v2/container/gset"
	"github.com/lxzan/gws"
	"log"
)

type Client struct {
	clientId    string                  // 客户端的唯一标识
	Socket      *gws.Conn               // 客户端链接
	FirstTime   uint64                  // 首次链接时间
	Message     chan *message.WResponse // 要发送给该客户端的消息
	CloseSignal chan struct{}           // 关闭信号(接收到信号后自动退出消息写协程)
	Tags        *gset.StrSet            // 标签(房间/分组)
	UserId      string                  // 用户Id
	UserNm      string                  // 用户名称(冗余)
}

func NewClient(clientId string, socket *gws.Conn, firstTime uint64) *Client {
	return &Client{
		clientId:    clientId,
		UserId:      clientId,
		Socket:      socket,
		FirstTime:   firstTime,
		Message:     make(chan *message.WResponse, 16),
		CloseSignal: make(chan struct{}, 1),
		Tags:        gset.NewStrSet(true),
	}
}

// WriteLoop 通过协程把发送给该客户端的消息发送给该客户端
func (c *Client) WriteLoop() {
	log.Println("发送消息协程启动111111")
	defer log.Println("发送消息协程结束222222")
	for {
		select {
		case msg := <-c.Message:
			if buffer, err := json.Marshal(msg); err == nil {
				log.Println("发送消息处理开始")
				_ = c.Socket.WriteMessage(gws.OpcodeText, buffer)
				log.Println("发送消息给客户端:", c.clientId, string(buffer))
			}
		case <-c.CloseSignal:
			log.Println("发送消息处理退出")
			return
		}
	}
}

// Put 把消息放到客户端的管道中,并等待管道自动发送出去
func (c *Client) Put(message *message.WResponse) {
	c.Message <- message
}

// Close 终止发送消息的协程,并关闭客户端
func (c *Client) Close() {
	c.Socket.WriteClose(1000, []byte(`{"event":"close","data":{"reason":"链接已经被关闭"}`))
	c.CloseSignal <- struct{}{}
}
